package com.gitee.qdbp.general.common.biz.sequence.service;

import java.util.Date;
import com.gitee.qdbp.general.common.api.sequence.model.SimpleSequenceRule;
import com.gitee.qdbp.general.common.api.sequence.model.StrongSequenceRule;
import com.gitee.qdbp.tools.utils.ConvertTools;
import com.gitee.qdbp.tools.utils.DateTools;
import com.gitee.qdbp.tools.utils.RandomTools;
import com.gitee.qdbp.tools.utils.StringTools;
import com.gitee.qdbp.tools.utils.VerifyTools;

/**
 * 序列号工具类
 *
 * @author zhaohuihua
 */
class SequenceTools {

    /**
     * 转换为字符串
     * 
     * @param bean 规则
     * @param hostCode 当前主机编号
     * @param index 当前值
     * @return 前缀+主机编号+当前值
     */
    public static String toString(SimpleSequenceRule bean, String hostCode, long index) {
        String prefix = bean.getPrefix();
        if (VerifyTools.isAllBlank(prefix, hostCode)) {
            return String.valueOf(index);
        } else {
            int digitNumber = bean.getDigitNumber();
            StringBuilder buffer = new StringBuilder();
            if (VerifyTools.isNotBlank(prefix)) {
                buffer.append(prefix);
            }
            if (VerifyTools.isNotBlank(hostCode)) {
                buffer.append(hostCode);
            }
            buffer.append(StringTools.pad(index, digitNumber));
            return buffer.toString();
        }
    }

    /** 根据规则计算下一个值 **/
    public static void next(SimpleSequenceRule bean) {
        int digitNumber = bean.getDigitNumber(); // 序号的位数
        Long currValue = bean.getCurrValue();
        if (currValue == null || currValue <= 0) {
            long initValue = bean.getInitValue(); // 初始值(0表示随机初始值, 大于0表示指定初始值)
            currValue = getInitValue(initValue, digitNumber);
        }

        bean.setCurrValue(currValue + 1);
    }

    /**
     * 转换为字符串
     * 
     * @param bean 规则
     * @param hostCode 当前主机编号
     * @param index 当前值
     * @return 前缀+主机编号+当前值
     */
    public static String toString(StrongSequenceRule bean, String hostCode, long index) {
        String prefix = bean.getPrefix();
        String currTime = bean.getCurrTime();
        int digitNumber = bean.getDigitNumber();
        StringBuilder buffer = new StringBuilder();
        if (VerifyTools.isNotBlank(prefix)) {
            buffer.append(prefix);
        }
        buffer.append(currTime);
        if (VerifyTools.isNotBlank(hostCode)) {
            buffer.append(hostCode);
        }
        buffer.append(StringTools.pad(index, digitNumber));
        return buffer.toString();
    }

    /** 根据规则计算下一个值 **/
    public static void next(StrongSequenceRule bean) {
        long initValue = bean.getInitValue(); // 初始值(0表示随机初始值, 大于0表示指定初始值)
        int digitNumber = bean.getDigitNumber(); // 序号的位数
        if (digitNumber <= 0) {
            digitNumber = 4;
        }

        String currTime = getCurrTime(bean.getTimeFormat());
        Long currValue = bean.getCurrValue();
        if (currValue == null || currValue <= 0) { // 初始值
            long newValue = getInitValue(initValue, digitNumber);
            bean.setCurrValue(newValue);
            bean.setCurrTime(currTime);
        } else {
            long newValue;
            if (bean.getCurrTime() != null && currTime.equals(bean.getCurrTime())) { // 同一时间
                newValue = currValue + 1L;
            } else { // 跨时间段了
                bean.setCurrTime(currTime);
                if (bean.getRound()) { // 每个时间段重新开始
                    newValue = getInitValue(initValue, digitNumber);
                } else { // 不重新开始
                    if (currValue >= Math.pow(10, bean.getDigitNumber()) - 1) {
                        // 跨时间段, currValue又已经达到或超过最大值了, 重新开始
                        newValue = getInitValue(initValue, digitNumber);
                    } else {
                        newValue = currValue + 1L;
                    }
                }
            }
            bean.setCurrValue(newValue);
        }
    }

    /** 将字类型合并为字符串 **/
    public static String joinSubtypes(String... subtypes) {
        return VerifyTools.isBlank(subtypes) ? "-" : ConvertTools.joinToString(subtypes, ":");
    }

    // 获取当前时间作为序号的前缀
    private static String getCurrTime(String timeFormat) {
        return DateTools.format(new Date(), timeFormat);
    }

    /**
     * 为防止根据订单号猜出销售量, 随机选择一个数字作为起始值<br>
     * initValue起始值配置为0才会启用随机起始值<br>
     * 4位时从100-200之间选择随机数, 5位时从1000-2000之间选择随机数, 以此类推...<br>
     * 
     * @param initValue 起始值配置值, 0表示随机初始值, 大于0表示指定初始值
     * @param digitNumber 序号位数配置值
     * @return 起始值
     */
    private static long getInitValue(long initValue, int digitNumber) {
        if (initValue > 0) {
            return initValue; // 配置时指定了起始值
        } else {
            if (digitNumber <= 1) {
                return 1;
            } else if (digitNumber == 2) {
                return RandomTools.generateNumber(1, 10);
            } else {
                int min = (int) Math.pow(10, digitNumber - 2);
                return RandomTools.generateNumber(min, min * 2);
            }
        }
    }
}
